package com.versiFramework.services{
    import com.versiFramework.core.IVersiClass;
    import com.versiFramework.events.versiEvent;
    import com.versiFramework.services.channel;
    import com.versiFramework.versi;
    
    import flash.events.Event;
    import flash.events.EventDispatcher;
    import flash.utils.ByteArray;
    
    import mx.collections.ArrayCollection;
    //import mx.messaging.Channel;
    //import mx.messaging.ChannelSet;
    import mx.messaging.Consumer;
    import mx.messaging.MultiTopicConsumer;
    import mx.messaging.Producer;
    //import mx.messaging.SubscriptionInfo;
    import mx.messaging.channels.AMFChannel;
    import mx.messaging.channels.PollingChannel;
    import mx.messaging.events.ChannelEvent;
    import mx.messaging.events.MessageAckEvent;
    import mx.messaging.events.MessageEvent;
    import mx.messaging.events.MessageFaultEvent;
    import mx.messaging.messages.AcknowledgeMessage;
    import mx.messaging.messages.AsyncMessage;
    
    public class producerService extends EventDispatcher implements IVersiClass {
		
		private var _producer:Producer;
		private var _reconnectAttempts:int = 0;
		private var _name:String;
		private var _gatewayid:String;
		private var _channelset:channel;
		
		private var _producerFault:Function;
		
		
		//* Properties *//
		public function get name():String
		{
			return _name;
		}
		public function set name(setVal:String):void
		{
			_name=setVal;
		}
				
		public function get gatewayid():String
		{
			return _gatewayid;
		}
		public function set gatewayid(setVal:String):void
		{
			_gatewayid=setVal;
		}		
		
		public function set reconnectAttempts(setVal:int):void
		{
			_reconnectAttempts=setVal;
		}
		
		public function get reconnectAttempts():int
		{
			return _reconnectAttempts
		}
		
		public function set channelset(setVal:channel):void {
			_channelset = setVal;
			_channelset.addEventListener(ChannelEvent.DISCONNECT,disconnected);
		}
		
		public function get channelset():channel {
			return _channelset;
		}
				
		//optional user defined handlers
		public function set producerFault(setVal:Function):void
		{
			if (_producer)
			{
				_producer.removeEventListener(MessageFaultEvent.FAULT, producerFault);
				if (setVal != null) _producer.addEventListener(MessageFaultEvent.FAULT, setVal);
			}
			_producerFault=setVal;
		}
		
		public function get producerFault():Function
		{
			return _producerFault != null ? _producerFault : onProducerFault
		}
		
		
		//* Message systems *//
		
		public function get producer():Producer
		{
			if (!_producer)
			{
				if (channelset.channelset)
				{
					_producer = new Producer();
					_producer.addEventListener(MessageFaultEvent.FAULT, producerFault);
					_producer.channelSet = channelset.channelset;
					_producer.destination = channelset.destination;
					_producer.reconnectAttempts=reconnectAttempts;
				}
				else
				{
					return null;
				}
			}
			return _producer
		}
		
		
		protected function onProducerFault(faultEvent:MessageFaultEvent):void
		{
			this.dispatchEvent(new versiEvent(faultEvent.type,faultEvent.message));
		}
				
		protected function disconnected(evt:Event):void
		{
			if (_producer)
			{
				_producer.removeEventListener(MessageFaultEvent.FAULT, producerFault);
				_producer.disconnect();
				_producer = null;
			}
		}
		
		public function simpleSend(message:String,subtopic:String=null,user:String=null):void
		{
			var prod:Producer = this.producer
			if 	(prod)
			{
				var msg:AsyncMessage = new AsyncMessage();
				msg.body = message;
				if (user) msg.headers["user"] = user;
				msg.headers["gatewayid"] = gatewayid;
				
				if (subtopic) prod.subtopic = subtopic;				
				prod.send(msg);
			}

		}
		
		public function send(body:*,header:Object=null,subtopic:String=null):void
		{
			var prod:Producer = this.producer
			if 	(prod)
			{
				var msg:AsyncMessage = new AsyncMessage();
				msg.body = body;
				if (header) msg.headers = header;
				msg.headers["gatewayid"] = gatewayid;
				if (subtopic) prod.subtopic = subtopic;
				prod.send(msg);
			}
		}
		
		
		
		//* Constructor *//
		public function producerService()
		{
			super();
		}




	}

}